home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / raid / devRaidLock.c < prev    next >
C/C++ Source or Header  |  1990-11-09  |  7KB  |  304 lines

  1. /* 
  2.  * devRaidLock.c --
  3.  *
  4.  *    Routines for locking and unlocking RAID stripes.
  5.  *    Note that because of the manner in which these routines are used,
  6.  *    stripes with the same number in different arrays (i.e. different
  7.  *    unit numbers) will share the same lock.  Therefore, care must be
  8.  *    taken to avoid unexpected deadlocks (i.e. a single process should never
  9.  *    simultaneously lock two stripes in different raid devices).
  10.  *    All locks are exclusive.
  11.  *
  12.  * Copyright 1989 Regents of the University of California
  13.  * Permission to use, copy, modify, and distribute this
  14.  * software and its documentation for any purpose and without
  15.  * fee is hereby granted, provided that the above copyright
  16.  * notice appear in all copies.  The University of California
  17.  * makes no representations about the suitability of this
  18.  * software for any purpose.  It is provided "as is" without
  19.  * express or implied warranty.
  20.  *
  21.  */
  22.  
  23. #ifndef lint
  24. static char rcsid[] = "$Header: /sprite/src/kernel/raid/RCS/devRaidLock.c,v 1.11 90/11/09 13:15:47 eklee Exp $ SPRITE (Berkeley)";
  25. #endif /* not lint */
  26.  
  27. #include "sync.h"
  28. #include <sprite.h>
  29. #include <stdio.h>
  30. #include "hash.h"
  31. #include "devRaid.h"
  32. #include "semaphore.h"
  33. #include "devRaidProto.h"
  34.  
  35. extern char *malloc();
  36.  
  37. #define LOCK_TABLE_SIZE    4096
  38.  
  39. static Hash_Table lockTable;
  40. static Sync_Semaphore mutex =
  41.     Sync_SemInitStatic("devRaidLock.c: Stripe Lock Table");
  42.  
  43.  
  44. /*
  45.  *----------------------------------------------------------------------
  46.  *
  47.  * Raid_InitStripeLocks --
  48.  *
  49.  *    Should be called at least once before calling any other procedure
  50.  *    from this module.
  51.  *
  52.  * Results:
  53.  *    None.
  54.  *
  55.  * Side effects:
  56.  *    Initializes stripe lock table.
  57.  *
  58.  *----------------------------------------------------------------------
  59.  */
  60.  
  61. void
  62. Raid_InitStripeLocks()
  63. {
  64.     static int    initialized = 0;
  65.  
  66.     MASTER_LOCK(&mutex);
  67.     if (initialized == 0) {
  68.     initialized = 1;
  69.         MASTER_UNLOCK(&mutex);
  70.     Hash_Init(&lockTable, 1000, 1);
  71.     } else {
  72.     MASTER_UNLOCK(&mutex);
  73.     }
  74. }
  75.  
  76.  
  77. /*
  78.  *----------------------------------------------------------------------
  79.  *
  80.  * Raid_SLockStripe --
  81.  *
  82.  * Results:
  83.  *    None.
  84.  *
  85.  * Side effects:
  86.  *    Share lock requested stripe.
  87.  *
  88.  *----------------------------------------------------------------------
  89.  */
  90.  
  91. void
  92. Raid_SLockStripe(raidPtr, stripe)
  93.     Raid *raidPtr;
  94.     int stripe;
  95. {
  96.     Hash_Entry        *hashEntryPtr;
  97.     Sync_Condition    *condPtr;
  98.     condPtr = (Sync_Condition *) Malloc(sizeof(Sync_Condition));
  99.  
  100.     MASTER_LOCK(&mutex);
  101.     hashEntryPtr = Hash_Find(&lockTable, (Address) stripe);
  102.     while ( Hash_GetValue(hashEntryPtr) != (char *) NIL ) {
  103.     Sync_MasterWait((Sync_Condition *) Hash_GetValue(hashEntryPtr),
  104.         &mutex, FALSE);
  105.         hashEntryPtr = Hash_Find(&lockTable, (Address) stripe);
  106.     }
  107. #ifdef TESTING
  108.     Sync_CondInit(condPtr);
  109. #endif TESTING
  110.     Hash_SetValue(hashEntryPtr, condPtr);
  111.     MASTER_UNLOCK(&mutex);
  112. }
  113.  
  114.  
  115. /*
  116.  *----------------------------------------------------------------------
  117.  *
  118.  * Raid_XLockStripe --
  119.  *
  120.  * Results:
  121.  *    None.
  122.  *
  123.  * Side effects:
  124.  *    Exclusively lock requested stripe.
  125.  *
  126.  *----------------------------------------------------------------------
  127.  */
  128. void
  129. Raid_XLockStripe(raidPtr, stripe)
  130.     Raid *raidPtr;
  131.     int stripe;
  132. {
  133.     Raid_SLockStripe(raidPtr, stripe);
  134.     Raid_LogStripe(raidPtr, stripe);
  135. }
  136.  
  137.  
  138. /*
  139.  *----------------------------------------------------------------------
  140.  *
  141.  * Raid_SUnlockStripe --
  142.  *
  143.  * Results:
  144.  *    None.
  145.  *
  146.  * Side effects:
  147.  *    Unlocks requested stripe.
  148.  *
  149.  *----------------------------------------------------------------------
  150.  */
  151.  
  152. void
  153. Raid_SUnlockStripe(raidPtr, stripe)
  154.     Raid *raidPtr;
  155.     int stripe;
  156. {
  157.     Hash_Entry        *hashEntryPtr;
  158.     Sync_Condition    *condPtr;
  159.  
  160.     MASTER_LOCK(&mutex);
  161.     hashEntryPtr = Hash_Find(&lockTable, (Address) stripe);
  162.     if ( Hash_GetValue(hashEntryPtr) == (char *) NIL ) {
  163.     MASTER_UNLOCK(&mutex);
  164.     panic("Error: UnlockStripe: Attempt to unlock unlocked stripe.");
  165.     }
  166.     condPtr = (Sync_Condition *) Hash_GetValue(hashEntryPtr);
  167.     Sync_MasterBroadcast(condPtr);
  168.     Hash_Delete(&lockTable, hashEntryPtr);
  169.     MASTER_UNLOCK(&mutex);
  170.     Free((char *) condPtr);
  171. }
  172.  
  173.  
  174. /*
  175.  *----------------------------------------------------------------------
  176.  *
  177.  * Raid_XUnlockStripe --
  178.  *
  179.  * Results:
  180.  *    None.
  181.  *
  182.  * Side effects:
  183.  *    Unlocks requested stripe.
  184.  *
  185.  *----------------------------------------------------------------------
  186.  */
  187.  
  188. void
  189. Raid_XUnlockStripe(raidPtr, stripe)
  190.     Raid *raidPtr;
  191.     int stripe;
  192. {
  193.     Raid_SUnlockStripe(raidPtr, stripe);
  194. }
  195.  
  196. /*
  197.  *----------------------------------------------------------------------
  198.  *
  199.  * Raid_Lock --
  200.  *
  201.  * Results:
  202.  *    None.
  203.  *
  204.  * Side effects:
  205.  *    Gains exclusive access to specified RAID device.
  206.  *
  207.  *----------------------------------------------------------------------
  208.  */
  209.  
  210. void
  211. Raid_Lock (raidPtr)
  212.     Raid *raidPtr;
  213. {
  214.     MASTER_LOCK(&raidPtr->mutex);
  215.     raidPtr->numWaitExclusive++;
  216.     while (raidPtr->numReqInSys != 0) {
  217.     Sync_MasterWait(&raidPtr->waitExclusive, &raidPtr->mutex, FALSE);
  218.     }
  219.     raidPtr->numWaitExclusive--;
  220.     raidPtr->numReqInSys = -1;
  221.     MASTER_UNLOCK(&raidPtr->mutex);
  222. }
  223.  
  224.  
  225. /*
  226.  *----------------------------------------------------------------------
  227.  *
  228.  * Raid_Unlock --
  229.  *
  230.  * Results:
  231.  *    None.
  232.  *
  233.  * Side effects:
  234.  *    Releases exclusive access to specified RAID device.
  235.  *
  236.  *----------------------------------------------------------------------
  237.  */
  238.  
  239. void
  240. Raid_Unlock (raidPtr)
  241.     Raid *raidPtr;
  242. {
  243.     MASTER_LOCK(&raidPtr->mutex);
  244.     raidPtr->numReqInSys = 0;
  245.     if (raidPtr->numWaitExclusive > 0) {
  246.     Sync_MasterBroadcast(&raidPtr->waitExclusive);
  247.     } else {
  248.     Sync_MasterBroadcast(&raidPtr->waitNonExclusive);
  249.     }
  250.     MASTER_UNLOCK(&raidPtr->mutex);
  251. }
  252.  
  253.  
  254. /*
  255.  *----------------------------------------------------------------------
  256.  *
  257.  * Raid_BeginUse --
  258.  *
  259.  * Results:
  260.  *    None.
  261.  *
  262.  * Side effects:
  263.  *
  264.  *----------------------------------------------------------------------
  265.  */
  266.  
  267. void
  268. Raid_BeginUse (raidPtr)
  269.     Raid *raidPtr;
  270. {
  271.     MASTER_LOCK(&raidPtr->mutex);
  272.     while (raidPtr->numReqInSys == -1 || raidPtr->numWaitExclusive > 0) {
  273.     Sync_MasterWait(&raidPtr->waitNonExclusive, &raidPtr->mutex, FALSE);
  274.     }
  275.     raidPtr->numReqInSys++;
  276.     MASTER_UNLOCK(&raidPtr->mutex);
  277. }
  278.  
  279.  
  280. /*
  281.  *----------------------------------------------------------------------
  282.  *
  283.  * Raid_EndUse --
  284.  *
  285.  * Results:
  286.  *    None.
  287.  *
  288.  * Side effects:
  289.  *
  290.  *----------------------------------------------------------------------
  291.  */
  292.  
  293. void
  294. Raid_EndUse (raidPtr)
  295.     Raid *raidPtr;
  296. {
  297.     MASTER_LOCK(&raidPtr->mutex);
  298.     raidPtr->numReqInSys--;
  299.     if (raidPtr->numReqInSys == 0) {
  300.     Sync_MasterBroadcast(&raidPtr->waitExclusive);
  301.     }
  302.     MASTER_UNLOCK(&raidPtr->mutex);
  303. }
  304.